package com.google.code.jtasks.adapters;

import java.util.Set;

import com.google.code.jtasks.manager.ITaskRepoManager;
import com.google.code.jtasks.model.IMappedTask.TaskField;
import com.google.code.jtasks.query.TaskQuery;
import com.google.code.jtasks.query.TaskQueryResult;

/**
 * <p>
 * {@link ITaskSystemAdapter} implementations are used by {@link ITaskRepoManager}s to provide functionality
 * specific to individual task systems. Users of the jTasks API should always use {@link ITaskRepoManager}s
 * instead of directly accessing {@link ITaskSystemAdapter}s.
 * </p>
 * <p>
 * Each {@link ITaskSystemAdapter} implementation provides access to the various objects required to work with
 * a specific task system.
 * </p>
 * <h4>Implementation Notes</h4>
 * <p>
 * When creating {@link ITaskSystemAdapter} implementations, the following should be kept in mind:
 * </p>
 * <ul>
 * <li>One {@link ITaskSystemAdapter} instance may be used to access multiple task repositories.</li>
 * <li>{@link ITaskSystemAdapter} instances should be stateless. If the {@link ITaskSystemAdapter} needs to
 * store/cache information about the task repositories it's used for (most will), it should use an
 * {@link IRepositoryMetadataProvider} instance's {@link RepositoryMetadata}s for this.</li>
 * </ul>
 * 
 * @param <R>
 *            the {@link RepositoryMetadata#getRepositoryData()} object type that will be used by
 *            this {@link ITaskSystemAdapter}
 * @param <S>
 *            the {@link RepositoryMetadata#getSessionData()} object type that will be used by this
 *            {@link ITaskSystemAdapter}
 */
public interface ITaskSystemAdapter<R, S>
{
	/**
	 * Identifies the {@link TaskField}s that are not supported by this {@link ITaskSystemAdapter}. These
	 * {@link TaskField}s must be optional ({@link TaskField#isOptional()} is <code>true</code>) and should
	 * only not be supported by the {@link ITaskSystemAdapter} if they are not present/represented in the
	 * underlying task system.
	 * 
	 * @return the {@link TaskField}s that are not supported by this {@link ITaskSystemAdapter}
	 */
	public Set<TaskField> getUnsupportedTaskFields();

	/**
	 * Runs the specified {@link TaskQuery} against the task repository identified by
	 * {@link TaskQuery#getConnectionSettings()}, returning the result as a {@link TaskQueryResult}.
	 * 
	 * @param query
	 *            the {@link TaskQuery} to be run
	 * @return the result of the {@link TaskQuery}, as a {@link TaskQueryResult}
	 */
	public TaskQueryResult runQuery(TaskQuery query);
}
